/**
 * 
 */
package bancosys.tec.services.input;

import static jmine.tec.di.DependencyInjectionMessages.FORMATO_INCORRETO;

import java.util.List;

import jmine.tec.di.injector.Injector;
import jmine.tec.di.type.TypeConvertionException;
import jmine.tec.services.api.Service;
import jmine.tec.services.api.ServiceExecutionException;
import jmine.tec.services.api.ServiceValidationExecutionException;
import bancosys.tec.persist.controller.PersistenceEnabledController;

/**
 * Servico que injeta dependencias antes de chamar os metodos {@link #validate()} e {@link #execute()}
 * 
 * @author takeshi
 */
final class InjectingDelegateService extends ForwardingService<PersistenceEnabledController> {
    private final List<Injector> injectors;

    private boolean staticsInjected;

    /**
     * Ctor
     * 
     * @param delegate o delegate propriamente dito
     * @param injectors os injetores
     */
    InjectingDelegateService(Service<?> delegate, List<Injector> injectors) {
        super(delegate);
        this.injectors = injectors;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<String> validate() {
        this.injectStaticEntries();
        return super.validate();
    }

    /**
     * Injeta coisas estaticas se necessario
     */
    private void injectStaticEntries() {
        if (!this.staticsInjected) {
            for (Injector injector : this.injectors) {
                try {
                    if (injector.getDependencyMetaData().getResolver().isStatic()) {
                        injector.doInject(this.getDelegate(), this.getServiceProperties());
                    }
                } catch (TypeConvertionException e) {
                    throw new ServiceValidationExecutionException(FORMATO_INCORRETO.create(injector.getDependencyMetaData()
                            .getPropertyName()), e);
                }
            }
            this.staticsInjected = true;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void execute() throws ServiceExecutionException {
        this.injectStaticEntries();
        try {
            for (Injector injector : this.injectors) {
                if (!injector.getDependencyMetaData().getResolver().isStatic()) {
                    injector.doInject(this.getDelegate(), this.getServiceProperties());
                }
            }
        } catch (TypeConvertionException e) {
            throw new ServiceExecutionException(e);
        }
        super.execute();
    }
}